﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using MenuGame2DXNA;

namespace MenuGame2DXNA
{
    public class Enemy : Character
    {

        private List<Point> _PointCol;

        /// <summary>
        /// Gets or sets the point col.
        /// </summary>
        /// <value>
        /// The point col.
        /// </value>
        public List<Point> PointCol
        {
            get { return _PointCol; }
            set { _PointCol = value; }
        }


        private short[,] _Obstructions;

        public short[,] Obstructions
        {
            get { return _Obstructions; }
            set { _Obstructions = value; }
        }

        private Point End = new Point(-1, -1);

        public Point End1
        {
            get { return End; }
            set { End = value; }
        }

        private int _MoveAllow = 1;

        public int MoveAllow
        {
            get { return _MoveAllow; }
            set { _MoveAllow = value; }
        }



        public Point pBom
        {
            get;
            set;
        }

        private Point _pWall = new Point(-1, -1);
        public Point pWall
        {
            get { return _pWall; }
            set { _pWall = value; }
        }

        private Point _pMove;

        public Point pMove
        {
            get { return _pMove; }
            set { _pMove = value; }
        }

        private List<Point> _Path;

        public List<Point> Path
        {
            get { return _Path; }
            set { _Path = value; }
        }

        public int Distance
        {
            get;
            set;
        }


              
        public Enemy(ContentManager content, string[] strTexture, int nTextures, Vector2 topleft, Vector2 size)
        {
            InitEnemy(content, strTexture, nTextures, ref topleft, ref size);
        }

        private void InitEnemy(ContentManager content, string[] strTexture, int nTextures, ref Vector2 _positionStart, ref Vector2 size)
        {
            TopLeft = new Vector2(0, 0);
            PositionStart = _positionStart;
            Size = size;
            Texture2D[] textures = new Texture2D[nTextures];

            for (int i = 0; i < nTextures; i++)
                textures[i] = content.Load<Texture2D>(strTexture[i]);

            ObjectVisible = new List<Sprite>();
            Sprite tempSprite = new UserControlledSprite(textures, TopLeft);
            tempSprite.Size = size;

            ObjectVisible.Add(tempSprite);
            nObjectVisible = 1;
        }

        public Enemy(ContentManager content, string strTexturePreFix, int nTextures, Vector2 topleft, Vector2 size, short[,] obstructions,sMainGame maingame)
        {
            _mainGame = maingame;
            string[] strTexture = new string[nTextures];
            for (int i = 0; i < nTextures; i++)
                strTexture[i] = strTexturePreFix + (i + 1).ToString("00");
            _Obstructions = new short[11, 11];
            for (int i = 0; i < 11; i++)
                for (int j = 0; j < 11; j++)
                    _Obstructions[i, j] = obstructions[i, j];

            InitEnemy(content, strTexture, nTextures, ref topleft, ref size);

        }


        private MOVEORIENT getMethol(Point pBegin, Point pEnd)
        {
            if (pBegin.X < pEnd.X)
                return MOVEORIENT.MOVEDOWN;
            if (pBegin.X > pEnd.X)
                return MOVEORIENT.MOVEUP;
            if (pBegin.Y < pEnd.Y)
                return MOVEORIENT.MOVERIGHT;
            if (pBegin.Y > pEnd.Y)
                return MOVEORIENT.MOVELEFT;
            return MOVEORIENT.NONE;
        }
        Point pEnd = new Point(0, 0);
        Vector2 posWait = new Vector2(0,0);
        public override void Update(GameTime gameTime, Color color)
        {
            ObjectVisible[0].Color = color;

            
            if (_Path != null && _Path.Count > 1)
            {

                if (MoveFlag == false)
                {
                    moveOrient = getMethol(Path[0], Path[1]);

                    Path.RemoveAt(0);
                    End = new Point(Path[0].X, Path[0].Y);                    
                }
                MoveRient(_Path[0]);

                base.Update(gameTime, color);
            }
            if (_pMove == pIndex)
            {

                moveOrient = getMethol(_pMove, End);

                MoveRient(End);
                base.Update(gameTime, color);
            }            
            
        }

        public void FindPathCharacter(BombManager bombManager, Point character, Tiles WallsManager)
        {
            if (Distance <= 4 && Distance > 1)
            {
                Algorithm algorithm = new Algorithm();
                List<Point> temp = new List<Point>();
                if (End1.X == -1)
                    temp = algorithm.findPath(pIndex, character, _Obstructions, 11, 11);
                else
                    temp = algorithm.findPath(End1, character, _Obstructions, 11, 11);
                if (temp.Count >= 2)
                    Path = temp;
            }
            else if (Distance > 4 && (_Path == null  || (_Path != null &&_Path.Count <= 1)))
            {
                FindPath(bombManager, WallsManager, 1, 0);
            }
        }
        
        private void MoveRient(Point p)
        {
            switch (moveOrient)
            {

                case MOVEORIENT.MOVERIGHT:

                    MoveRight(true);
                    break;
                case MOVEORIENT.MOVELEFT:

                    MoveLeft(true);
                    break;
                case MOVEORIENT.MOVEDOWN:

                    MoveDown(true);
                    break;
                case MOVEORIENT.MOVEUP:

                    MoveUp(true);
                    break;
            }
            

        }

        public override void AddBomb(GameTime gameTime)
        {
            _mainGame.bombManager.AddBoom(this, gameTime, (short)ID);

        }


        public void SetObstructions(short[,] obstructions, Point pEnemy, Point pCharacter)
        {
            for (int i = 0; i < 11; i++)
                for (int j = 0; j < 11; j++)
                    _Obstructions[i, j] = obstructions[i, j];

            for (int i = 0; i < _PointCol.Count; i++)
                _Obstructions[_PointCol[i].X, _PointCol[i].Y]++;

            //for (int i = 0; i < 11; i++)
            //    for (int j = 0; j < 11; j++)
            //        if (obstructions[i, j] == 10 || obstructions[i, j] == 11 || obstructions[i, j] == 12 || obstructions[i, j] == 13)
            //        {
            //            _Obstructions[i, j] = 1;
            //            for (int k = 0; k < 3; k++)
            //                if (i + k + 1 < 11 && _Obstructions[i + k + 1, j] == 0 && new Point(i + k + 1, j) != pEnemy && new Point(i + k + 1, j) != pCharacter)
            //                    _Obstructions[i + k + 1, j] = 1;
            //                else break;
            //            for (int k = 0; k < 3; k++)
            //                if (j + k + 1 < 11 && _Obstructions[i, j + k + 1] == 0 && new Point(i, j + k + 1) != pEnemy && new Point(i + k + 1, j) != pCharacter)
            //                    _Obstructions[i, j + k + 1] = 1;
            //                else break;
            //            for (int k = 0; k < 3; k++)
            //                if (i - k - 1 >= 0 && _Obstructions[i - k - 1, j] == 0 && new Point(i - k - 1, j) != pEnemy && new Point(i + k + 1, j) != pCharacter)
            //                    _Obstructions[i - k - 1, j] = 1;
            //                else break;
            //            for (int k = 0; k < 3; k++)
            //                if (j - k - 1 >= 0 && _Obstructions[i, j - k - 1] == 0 && new Point(i, j - k - 1) != pEnemy && new Point(i + k + 1, j) != pCharacter)
            //                    _Obstructions[i, j - k - 1] = 1;
            //                else break;
            //        }
            _Obstructions[pCharacter.X, pCharacter.Y] = 0;

        }

        public void FindPath(BombManager bombManager, Tiles WallsManager, int checkWall, int typeEscape)
        {
            Algorithm algorithm = new Algorithm();
            algorithm.pFindSpread(pIndex, _Obstructions, 11, 11);
            if(checkWall == 1)
                for (int i = 0; i < algorithm.npSpread; i++)
                {
                    if ((algorithm.pSpread[i].X + 1 < 11 && WallsManager[new Point(algorithm.pSpread[i].X + 1, algorithm.pSpread[i].Y)] == 0) &&
                        (algorithm.pSpread[i].X - 1 >= 0 && WallsManager[new Point(algorithm.pSpread[i].X - 1, algorithm.pSpread[i].Y)] == 0) &&
                        (algorithm.pSpread[i].Y + 1 < 11 && WallsManager[new Point(algorithm.pSpread[i].X, algorithm.pSpread[i].Y + 1)] == 0) &&
                        (algorithm.pSpread[i].Y - 1 >= 0 && WallsManager[new Point(algorithm.pSpread[i].X, algorithm.pSpread[i].Y - 1)] == 0))
                    {                   
                        algorithm.pSpread.RemoveAt(i);
                        i--;
                        algorithm.npSpread--;
                    }
                }

            
            List<int> notMoveCol = new List<int>();
            List<int> notMoveRow = new List<int>();
            for (int k = 0; k < bombManager.BombCount; k++)
            {
                if (bombManager.checkbombExist(k))
                {
                    if (bombManager[k].PIndex.X % 2 == 1 && bombManager[k].PIndex.Y % 2 == 0)
                        notMoveCol.Add(bombManager[k].PIndex.Y);
                    if (bombManager[k].PIndex.X % 2 == 0 && bombManager[k].PIndex.Y % 2 == 1)
                        notMoveRow.Add(bombManager[k].PIndex.X);
                    if (bombManager[k].PIndex.X % 2 == 0 && bombManager[k].PIndex.Y % 2 == 0)
                    {
                        notMoveCol.Add(bombManager[k].PIndex.Y);
                        notMoveRow.Add(bombManager[k].PIndex.X);
                    }
                }
            }
            if (typeEscape == 0)
                for (int h = 0; h < algorithm.npSpread; h++)
                {
                    int t = 0;
                    for (int k = 0; k < notMoveRow.Count; k++)
                        if (algorithm.pSpread[h].X == notMoveRow[k])
                        {
                            t = 1;
                            break;
                        }
                    for (int l = 0; l < notMoveCol.Count; l++)
                        if (algorithm.pSpread[h].Y == notMoveCol[l])
                        {
                            t = 1;
                            break;
                        }
                    if (t == 1)
                    {
                        continue;
                    }
                    else
                    {
                        if (End1.X == -1)
                            _Path = algorithm.findPath(pIndex, algorithm.pSpread[h], _Obstructions, 11, 11);
                        else
                            _Path = algorithm.findPath(End1, algorithm.pSpread[h], _Obstructions, 11, 11);

                        break;
                    }
                }
            else
                for (int h = algorithm.npSpread - 1; h >= 0; h--)
                {
                    int t = 0;
                    for (int k = 0; k < notMoveRow.Count; k++)
                        if (algorithm.pSpread[h].X == notMoveRow[k])
                        {
                            t = 1;
                            break;
                        }
                    for (int l = 0; l < notMoveCol.Count; l++)
                        if (algorithm.pSpread[h].Y == notMoveCol[l])
                        {
                            t = 1;
                            break;
                        }
                    if (t == 1)
                    {
                        continue;
                    }
                    else
                    {
                        if (End1.X == -1)
                            _Path = algorithm.findPath(pIndex, algorithm.pSpread[h], _Obstructions, 11, 11);
                        else
                            _Path = algorithm.findPath(End1, algorithm.pSpread[h], _Obstructions, 11, 11);

                        break;
                    }
                }
        }

    }
}
